* Determines out-of-sample R² with p-values, and utility gains
* "modelmean" refers to the historical mean corresponding to a model, i.e. the one using the same estimation period
* "s..." indicates the use of simple returns rather than log returns 
* The file also implements a test of utility gains (H_0 = 0) not reported in the paper


capture drop oos*
capture drop cdu*

novarabbrev capture drop lnr
novarabbrev capture drop r
*returns used below
gen lnr=lnexret
gen r=exret


*Modulus to pick only nonoverlapping returns
if $freq==4{
	local modul=10
}
if $freq==12{
	local modul=100
}


local firstdates $firstpred $start2

foreach date of local firstdates {
	local endused=$end1

	
	
	
	capture drop wealth*
	capture drop turnover*
	capture drop copt*
	
	
	global evalfirstpred=`date'
	



		local means `" "model" "'

		
		
		*R2
		
		capture drop x*
		gen x=(pred-lnr)^2 
		sum x if yy>=$evalfirstpred & yy<=`endused'
		local sqpred=r(sum)
		
		foreach mean of local means{
			gen oosr2`mean'`date'`endused'=.
			capture drop x*
			gen x=(`mean'mean-lnr)^2 
			sum x if yy>=$evalfirstpred & yy<=`endused'
			local sq`mean'=r(sum)
			
			replace oosr2`mean'`date'`endused'=(1-`sqpred'/`sq`mean'')*100 in 1		
		}
		
		
		
		*Clark-West
		foreach mean of local means{
		
			capture drop x*
			gen xf=(lnr-`mean'mean)^2-((lnr-pred)^2-(`mean'mean-pred)^2)				
		
			if $h==1{
				reg xf if yy>=$evalfirstpred & yy<=`endused'
			}
			if $h>1{
				newey xf if yy>=$evalfirstpred & yy<=`endused', lag($h)
			}
			replace oosr2`mean'`date'`endused' = ttail(e(df_r),_coef[_cons]/_se[_cons]) in 2
		
		
		}
					
				
		


	*Performance analysis

	matrix df = (1, -1, -$gamma/2, $gamma/2)

	capture drop wopt* 
	capture drop opt*
	foreach var of varlist spred smodelmean {
		gen wopt`var'= max($minall,min($maxall,`var'/$gamma/smodelvar))
		gen opt`var'= wopt`var'*r+riskfree
	}
	gen woptbuyhold=1
	gen optbuyhold=woptbuyhold*r+riskfree

	
	
	*Determine Certainty Equivalents 
	

	local vars `" "optspred" "optsmodelmean"  "optbuyhold" "'
 
	foreach var of local vars{
		sum `var' if yy>=$evalfirstpred & yy<=`endused' & int((mod(yyy,`modul')+$h -1)/$h )==(mod(yyy,`modul')+$h -1)/$h
			
		local cee`var'=r(mean)-0.5*$gamma*r(Var)
		local m`var'=r(Var)
		local n=r(N)
			
		gen wealthtotal`var'=1+`var' 
		gen wealthrisky`var'=w`var'*(1+riskfree+r)
		gen turnover`var'=abs(wealthrisky`var'/wealthtotal`var'-w`var'[_n+1])	
	
		replace turnover`var'=0 if yy==`endused'
		
		local cost=0.002
		gen c`var'=(1+`var')*(1-`cost'*turnover`var')-1
	
		sum c`var' if yy>=$evalfirstpred & yy<=`endused' & int((mod(yyy,`modul')+$h -1)/$h )==(mod(yyy,`modul')+$h -1)/$h
		
		local ccee`var'=r(mean)-0.5*$gamma*r(Var)
		local cm`var'=r(Var)
	
		
	
		capture gen cdu`var'`date'`endused'=.
		replace cdu`var'`date'`endused'=(`cceeoptspred'-`ccee`var'')*100*($freq/$h) in 1
				
		cor coptspred `var' if yy>=$evalfirstpred & yy<=`endused' & int((mod(yyy,`modul')+$h -1)/$h )==(mod(yyy,`modul')+$h -1)/$h, cov
		
		
		local cc=_result(4)
		matrix  comega = (`cmoptspred',`cc',0,0 \ `cc',`cm`var'',0,0 \ 0,0,2*`cmoptspred'^2,2*`cc'^2 \ 0,0,2*`cc'^2,2*`cm`var''^2)
		matrix cp=df*comega*df'	
		replace cdu`var'`date'`endused'=2*normprob(-abs(cdu`var'`date'`endused'[1]/100/(cp[1,1])^.5*`n'^0.5)) in 2
		
	
}

	
}


*R2 Analysis with end=end2

local firstdates $firstpred 


foreach date of local firstdates {
	local endused=$end2

	
	
	capture drop wealth*
	capture drop turnover*
	capture drop copt*
	
	
	global evalfirstpred=`date'
	



		local means `" "model" "'

		
		
		*R2
		
		capture drop x*
		gen x=(pred-lnr)^2 
		sum x if yy>=$evalfirstpred & yy<=`endused'
		local sqpred=r(sum)
		
		foreach mean of local means{
			gen oosr2`mean'`date'`endused'=.
			capture drop x*
			gen x=(`mean'mean-lnr)^2 
			sum x if yy>=$evalfirstpred & yy<=`endused'
			local sq`mean'=r(sum)
			
			replace oosr2`mean'`date'`endused'=(1-`sqpred'/`sq`mean'')*100 in 1		
		}
		
		
		
		*Clark-West
		foreach mean of local means{
		
			capture drop x*
			gen xf=(lnr-`mean'mean)^2-((lnr-pred)^2-(`mean'mean-pred)^2)				
		
			if $h==1{
				reg xf if yy>=$evalfirstpred & yy<=`endused'
			}
			if $h>1{
				newey xf if yy>=$evalfirstpred & yy<=`endused', lag($h)
			}
			replace oosr2`mean'`date'`endused' = ttail(e(df_r),_coef[_cons]/_se[_cons]) in 2
		
		}
					
				
		


	*Performance analysis

	matrix df = (1, -1, -$gamma/2, $gamma/2)

	capture drop wopt* 
	capture drop opt*
	foreach var of varlist spred smodelmean {
		gen wopt`var'= max($minall,min($maxall,`var'/$gamma/smodelvar))
		gen opt`var'= wopt`var'*r+riskfree
	}
	gen woptbuyhold=1
	gen optbuyhold=woptbuyhold*r+riskfree

	
	
	*Determine Certainty Equivalents 
	

	local vars `" "optspred" "optsmodelmean" "optbuyhold" "'
 
	foreach var of local vars{
		sum `var' if yy>=$evalfirstpred & yy<=`endused' & int((mod(yyy,`modul')+$h -1)/$h )==(mod(yyy,`modul')+$h -1)/$h
	
		local cee`var'=r(mean)-0.5*$gamma*r(Var)
		local m`var'=r(Var)
		local n=r(N)
			
		gen wealthtotal`var'=1+`var' 
		gen wealthrisky`var'=w`var'*(1+riskfree+r)
		gen turnover`var'=abs(wealthrisky`var'/wealthtotal`var'-w`var'[_n+1])	
	
		replace turnover`var'=0 if yy==$end1
		
		local cost=0.002
		gen c`var'=(1+`var')*(1-`cost'*turnover`var')-1
	
	
		sum c`var' if yy>=$evalfirstpred & yy<=`endused' & int((mod(yyy,`modul')+$h -1)/$h )==(mod(yyy,`modul')+$h -1)/$h
		local ccee`var'=r(mean)-0.5*$gamma*r(Var)
		local cm`var'=r(Var)
	
		
	
		capture gen cdu`var'`date'`endused'=.
		replace cdu`var'`date'`endused'=(`cceeoptspred'-`ccee`var'')*100*($freq/$h) in 1
				
		cor coptspred `var' if yy>=$evalfirstpred & yy<=`endused' & int((mod(yyy,`modul')+$h -1)/$h )==(mod(yyy,`modul')+$h -1)/$h, cov
		local cc=_result(4)
		matrix  comega = (`cmoptspred',`cc',0,0 \ `cc',`cm`var'',0,0 \ 0,0,2*`cmoptspred'^2,2*`cc'^2 \ 0,0,2*`cc'^2,2*`cm`var''^2)
		matrix cp=df*comega*df'	
		replace cdu`var'`date'`endused'=2*normprob(-abs(cdu`var'`date'`endused'[1]/100/(cp[1,1])^.5*`n'^0.5)) in 2
		
	
}
	
	

}
